/**
 @file        ScatterWeb.Mutex.c
 @ingroup     system						
 @brief       simple mutex for only two(!) concurrent locks
 @version     $0.1$					
 @since       1.0
 @author      Andreas Schlueter

 

 $Id$
 */

#include <ScatterWeb.Mutex.h>
#include <ScatterWeb.System.h>

/**
 * @brief device mutex for two consumer
 *
 */
typedef struct {
	uint8_t value;
	fp_consumer waiting;
}mutex_t;


///the mutexes
static volatile mutex_t mutexes[MUTEX_NUM];

/**
 * @brief	initializes mutex
 * @param m enumeration mutex
 */
void mutex_init(enum mutex_dev m){
	mutexes[m].value = 1;
	mutexes[m].waiting = NULL;
}

/**
 * @brief	locks mutex
 * @param m enumeration mutex
 * @param c consumer called when lock is possible
 */
void mutex_lock(enum mutex_dev m, fp_consumer c){
	dint();
	if(mutexes[m].value==1){
		mutexes[m].value = 0;
		mutexes[m].waiting = NULL;
		eint();
		c(m);
	}else{
		mutexes[m].waiting = c;
		eint();
	}
}

/**
 * @brief	unlocks mutex and calls a waiting consumer
 * @param m enumeration mutex
 */
void mutex_unlock(enum mutex_dev m){
	dint();
	mutexes[m].value = 1;
	if(mutexes[m].waiting){
		eint();
		mutexes[m].waiting(m);
	}
	else
		eint();
}

/**
 * @brief	checks mutex status
 * @param m enumeration mutex
 * @return true, if mutex is locked
 */

bool mutex_locked(enum mutex_dev m){
	return mutexes[m].value == 0;
}

